import hashlib

from Crypto.Hash import SHA1
from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_v1_5,PKCS1_OAEP
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad, unpad
from Crypto.Util.number import bytes_to_long, long_to_bytes
import base64

import Global


class Crpty:
    @staticmethod
    def md5(text):
        """计算字符串的 MD5 哈希值"""
        md5 = hashlib.md5()
        md5.update(text.encode('utf-8'))  # 将字符串编码为 bytes
        return md5.hexdigest()  # 返回 32 位十六进制哈希值
    @staticmethod
    def sha256(text):
        # 创建 Sha256 哈希对象
        sha256 = hashlib.sha256()
        # 更新哈希对象（输入要加密的文本）
        sha256.update(text.encode('utf-8'))
        # 获取加密后的十六进制字符串
        encrypted_text = sha256.hexdigest()
        return encrypted_text
    # @staticmethod
    # def rsa_encrypt(public_key, plaintext: bytes) -> str:
    #     """使用公钥分块加密数据，返回Base64字符串"""
    #     public_key = RSA.import_key(public_key)
    #     key_size = public_key.size_in_bytes()
    #     max_block_size = key_size - 11  # PKCS#1 v1.5填充最大块
    #     cipher_blocks = []
    #
    #     for i in range(0, len(plaintext), max_block_size):
    #         block = plaintext[i:i + max_block_size]
    #         cipher_block = public_key.encrypt(block, None)[0]
    #         cipher_blocks.append(cipher_block)
    #
    #     ciphertext = b''.join(cipher_blocks)
    #     return base64.b64encode(ciphertext).decode()


    # @staticmethod
    # def rsa_encrypt(public_key_pem, message):
    #     try:
    #         # 加载公钥
    #         public_key = RSA.import_key(public_key_pem)
    #         # 创建加密器
    #         cipher = PKCS1_v1_5.new(public_key)
    #         # 计算最大明文长度
    #         max_length = public_key.size_in_bytes() - 11
    #         # 如果消息长度超过最大长度，需要分块加密
    #         if not isinstance(message, str):
    #             return "Message must be a string."
    #         if len(message) > max_length:
    #             # 拆分消息
    #             chunks = [message[i:i + max_length] for i in range(0, len(message), max_length)]
    #             # 加密每个块
    #             encrypted_chunks = [cipher.encrypt(chunk.encode()) for chunk in chunks]
    #             # 返回base64编码的加密结果，使用'|'连接
    #             return '|'.join(base64.b64encode(chunk).decode('utf-8') for chunk in encrypted_chunks)
    #         else:
    #             # 如果消息长度小于等于最大长度，直接加密
    #             encrypted_message = cipher.encrypt(message.encode())
    #             return base64.b64encode(encrypted_message).decode('utf-8')
    #     except (ValueError, TypeError) as e:
    #         Global.LOGE(f"RSA加密失败: {str(e)}")
    #     return ""

    # @staticmethod
    # def rsa_decrypt(public_key_pem, ciphertext_base64):
    #     try:
    #         # 加载公钥
    #         public_key = RSA.import_key(public_key_pem)
    #         # Base64解码
    #         ciphertext = base64.b64decode(ciphertext_base64)
    #         # 获取密钥字节长度
    #         key_size = public_key.size_in_bytes()
    #
    #         if len(ciphertext) % key_size != 0:
    #             raise RuntimeError(f"密文长度不匹配，应为{key_size}字节的整数倍")
    #
    #         plaintext = b''
    #         # 分块解密
    #         for i in range(0, len(ciphertext), key_size):
    #             chunk = ciphertext[i:i + key_size]
    #             # 手动解密（c^e % n）
    #             c = int.from_bytes(chunk, byteorder='big')
    #             m = pow(c, public_key.e, public_key.n)
    #             # 转换为字节并去除填充
    #             decrypted_bytes = m.to_bytes((m.bit_length() + 7) // 8, byteorder='big')
    #             # 去除 PKCS#1 v1.5 填充
    #             if decrypted_bytes[0:2] != b'\x00\x02':
    #                 raise ValueError("解密错误：无效的填充格式")
    #             # 查找填充结束位置
    #             padding_end = decrypted_bytes.find(b'\x00', 2)
    #             if padding_end < 0:
    #                 raise ValueError("解密错误：无效的填充格式")
    #             # 提取明文
    #             plaintext += decrypted_bytes[padding_end + 1:]
    #
    #         # 尝试解码为 UTF-8，如果失败则返回原始字节
    #         try:
    #             return plaintext.decode('utf-8')
    #         except UnicodeDecodeError:
    #             return plaintext
    #     except Exception as e:
    #         print(f"RSA解密失败: {str(e)}")
    #     return ""
    @staticmethod
    def rsa_encrypt(public_key, plaintext):
        """RSA 分块加密"""
        rsa_key =RSA.import_key(public_key)
        cipher = PKCS1_v1_5.new(rsa_key)
        key_length = rsa_key.size_in_bytes()
        max_block_size = key_length - 11  # PKCS#1 v1.5 填充最大块

        ciphertext = b''
        for i in range(0, len(plaintext), max_block_size):
            block = plaintext[i:i + max_block_size]
            encrypted_block = cipher.encrypt(block.encode())
            ciphertext += encrypted_block

        return base64.b64encode(ciphertext).decode()

    @staticmethod
    def rsa_decrypt(public_key_pem: str, ciphertext_b64: str) -> str:
        """使用公钥解密私钥加密的数据（对应 C++ 的 RSA_public_decrypt 逻辑）"""
        # 加载公钥
        rsa_key = RSA.import_key(public_key_pem)
        key_size = rsa_key.size_in_bytes()  # 密钥字节长度（如 256）
        # Base64 解码
        ciphertext = base64.b64decode(ciphertext_b64)
        # 检查密文长度是否为密钥长度的整数倍
        if len(ciphertext) % key_size != 0:
            raise ValueError(
                f"Invalid ciphertext length: must be multiples of {key_size} bytes, "
                f"got {len(ciphertext)}"
            )

        # 分块解密
        plaintext = []
        for offset in range(0, len(ciphertext), key_size):
            # 获取当前分块
            chunk = ciphertext[offset:offset + key_size]
            # 将密文转换为整数
            ciphertext_int = bytes_to_long(chunk)
            # 使用公钥解密：m = c^e mod n
            plaintext_int = pow(ciphertext_int, rsa_key.e, rsa_key.n)
            # 将整数转换回字节
            plaintext_bytes = long_to_bytes(plaintext_int, key_size)
            # 手动去除 PKCS1_v1_5 填充
            try:
                # 检查格式：0x00 0x02 ... 0x00 [明文]
                if plaintext_bytes[0:2] != b'\x00\x01':
                    raise ValueError("Invalid padding header")
                # 查找 0x00 分隔符
                pad_end = plaintext_bytes.find(b'\x00', 2)
                if pad_end == -1:
                    raise ValueError("Padding separator not found")
                # 提取明文部分
                plaintext.append(plaintext_bytes[pad_end + 1:].decode('utf-8'))
            except Exception as e:
                raise ValueError(f"Padding error at block {offset // key_size}: {str(e)}")
        return ''.join(plaintext)
    @staticmethod
    def is_base64(s):
        # 检查字符串是否为空
        if not isinstance(s, str) or len(s) == 0:
            return False
        # 尝试解码
        try:
            # 由于某些 Base64 字符串可能缺少填充，先替换非法字符并填充
            s = s.strip().replace(' ', '+')
            missing_padding = len(s) % 4
            if missing_padding != 0:
                s += '=' * (4 - missing_padding)
            decoded = base64.b64decode(s)
            # 再次编码后是否与原字符串一致（忽略换行符等）
            return base64.b64encode(decoded).decode().rstrip() == s.rstrip()
        except:
            return False

    @staticmethod
    def aes_ecb_pkcs5_decrypt(encrypted_hex, key):
        """
        使用 AES/ECB/PKCS5Padding 解密16进制编码的密文
        :param encrypted_hex: 16进制编码的密文
        :param key: 密钥字符串
        :return: 解密后的字符串
        """
        # 将密钥字符串转换为字节串
        key_bytes = key.encode('utf-8')

        # 确保密钥长度为16字节
        if len(key_bytes) != 16:
            raise ValueError("密钥长度必须为16字节")
        # 将16进制字符串转换为字节串
        encrypted_data = bytes.fromhex(encrypted_hex)
        # 创建 AES/ECB 模式解密器
        cipher = AES.new(key_bytes, AES.MODE_ECB)
        # 解密数据
        decrypted_padded_data = cipher.decrypt(encrypted_data)
        # 移除 PKCS5 填充
        decrypted_data = unpad(decrypted_padded_data, AES.block_size)
        # 将字节串转换为字符串
        decrypted_string = decrypted_data.decode('utf-8')
        return decrypted_string

    @staticmethod
    def aes_ecb_pkcs5_encrypt(input_string, key):
        """
        使用 AES/ECB/PKCS5Padding 加密字符串
        :param input_string: 输入字符串
        :param key: 密钥字符串
        :return: 16进制编码的密文
        """
        # 将密钥字符串转换为字节串
        key_bytes = key.encode('utf-8')
        # 确保密钥长度为16字节
        if len(key_bytes) != 16:
            raise ValueError("密钥长度必须为16字节")
        # 创建 AES/ECB 模式加密器
        cipher = AES.new(key_bytes, AES.MODE_ECB)
        # 对输入字符串进行 PKCS5 填充
        padded_data = pad(input_string.encode('utf-8'), AES.block_size)
        # 加密数据
        encrypted_data = cipher.encrypt(padded_data)
        # 将密文转换为16进制字符串
        encrypted_hex = encrypted_data.hex()
        return encrypted_hex
